React is the most used front end library for building modern, interactive front end web apps. It can also be used to build mobile apps.
In this article, we’ll look at various less common features that are helpful for developing React apps.
Create React Elements with Strings
We can reference React elements with strings instead of JSX. HTML elements can be written with strings instead of JSX.
For instance, we can write the following code:
import React from "react";
const Component = "div";
export default function App() {
return <Component className="App">hello</Component>;
}
In the code above, we have Component
set to 'div'
, which means that Component
is a div element. This is good because we can change the Component
‘s element tag dynamically without hassle.
For instance, we can make a toggle to switch between div and p as follows:
import React from "react";
export default function App() {
const [Component, setComponent] = React.useState("div");
return (
<>
<button
onClick={() =>
setComponent(Component => (Component === "div" ? "p" : "div"))
}
>
Toggle Tag
</button>
<Component className="App">hello</Component>
</>
);
}
In the code above, we have a button to toggle the tag of Component
between div and p.
Therefore, when we click the button, we’ll see that the tag of Component
switches between div and p as we click the button.
Retain Previous Values
We can use the useRef
hook to retain the previous value of a prop or state.
For instance, we can keep the old value and the new value of a state as follows:
import React from "react";
export default function App() {
const [name, setName] = React.useState("bob");
const prevNameRef = React.useRef("");
React.useEffect(() => {
prevNameRef.current = name;
}, [name]);
const prevName = prevNameRef.current;
return (
<div>
<button
onClick={() => setName(name => (name === "bob" ? "jane" : "bob"))}
>
Toggle Name
</button>
<p>Current name:</p>
<p>{name}</p>
<p>Previous name:</p>
<p>{prevName}</p>
</div>
);
}
In the code above, we have the name
state and the setName
function to set the value of name
.
Then in the button, we call the setName
function when we click it. It toggles between 'bob'
and 'jane'
.
In the useEffect
hook, we watch the value of name
, which sets the prevNameRef.current
to name
to keep the original value. Then we set prevNameRef.current
to prevName
so to keep things short in the return
statement.
In the end, we’ll see the old and new values display in the returned JSX.
Use React.useRef
for Flexible Non-Stale Value Checks
One way to check if some data is loaded when the component loads are to use the useRef
hook to keep track of whether the piece of data is loaded.
For instance, we can write the following code to do that:
import React from "react";
export default function App() {
const [name, setName] = React.useState("");
const loaded = React.useRef(false);
React.useEffect(() => {
if (!loaded.current) {
setName("bob");
}
loaded.current = true;
return () => (loaded.current = false);
});
return <div>{name}</div>;
}
In the code above, we check the useEffect
callback that checks if loaded.current
is true
. If it’s not, then we call setName
to set the name
state’s value.
In the useEffect
callback, we also have:
return () => (loaded.current = false);
to reset loaded.current
to false
when App
unloads.
Therefore, we’ll see that the component loads with the name ‘bob’ displayed.
Memoize Values with the useMemo Hook
We can also use the useMemo
hook to create a memoized values, which means that it’s cached as long as it or its dependencies don’t change.
useMemo
runs during rendering. Therefore, we shouldn’t run anything that we wouldn’t do during rendering.
It’s used as a performance optimization, but it’s not a guarantee of the integrity of the value because it might change later.
For instance, we can use it as follows:
import React from "react";
export default function App() {
const [firstName, setFirstName] = React.useState("");
const [lastName, setLastName] = React.useState("");
const name = React.useMemo(() => `${firstName} ${lastName}`, [
firstName,
lastName
]);
return (
<div>
<input value={firstName} onChange={e => setFirstName(e.target.value)} />
<input value={lastName} onChange={e => setLastName(e.target.value)} />
<p>{name}</p>
</div>
);
}
In the code above, we used useMemo
to watch firstName
and lastName
‘s values and then derive a new value name
from combining the 2.
Then when we enter text into the input, we’ll see that it updates the value of name
. However, it’ll cache the existing value if firstName
or lastName
don’t change.
Conclusion
We can use the useRef
and useMemo
hooks to cache data. Also, we can create HTML elements with strings. This means that we can render HTML elements dynamically.